package com.itbaizhan.shopping_user_service.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.itbaizhan.shopping_common.pojo.ShoppingUser;
import com.itbaizhan.shopping_common.result.BusException;
import com.itbaizhan.shopping_common.result.CodeEnum;
import com.itbaizhan.shopping_common.service.ShoppingUserService;
import com.itbaizhan.shopping_common.util.Md5Util;
import com.itbaizhan.shopping_user_service.mapper.ShoppingUserMapper;
import com.itbaizhan.shopping_user_service.util.JwtUtils;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 商城用户服务实现
 */
@DubboService
@Service
public class ShoppingUserServiceImpl implements ShoppingUserService {
	
	@Autowired
	private ShoppingUserMapper shoppingUserMapper;
	
	@Autowired
	private RedisTemplate redisTemplate;
	
	/**
	 * 注册时向redis保存手机号+验证码
	 *
	 * @param phone
	 * @param checkCode
	 */
	public void saveRegisterCheckCode(String phone, String checkCode) {
		ValueOperations valueOperations = redisTemplate.opsForValue();
		valueOperations.set("registerCode:" + phone, checkCode, 300, TimeUnit.SECONDS);
	}
	
	/**
	 * 注册时验证手机号+验证码
	 *
	 * @param phone
	 * @param checkCode
	 */
	public void registerCheckCode(String phone, String checkCode) {
		ValueOperations valueOperations = redisTemplate.opsForValue();
		// 验证验证码
		
		String checkCodeRedis = (String) valueOperations.get("registerCode:" + phone);
		if (!checkCode.equals(checkCodeRedis)) {
			throw new BusException(CodeEnum.REGISTER_CODE_ERROR);
		}
	}
	
	/**
	 * 用户名密码登录
	 *
	 * @param username
	 * @param password
	 * @return
	 */
	public String loginPassword(String username, String password) {
		
		QueryWrapper<ShoppingUser> wrapper = new QueryWrapper();
		wrapper.eq("username", username);
		
		ShoppingUser shoppingUser = shoppingUserMapper.selectOne(wrapper);
		//验证用户名
		if (shoppingUser == null){
			throw new BusException(CodeEnum.USERNAME_PASSWORD_ERROR);
		}
		//验证密码
		boolean verify = Md5Util.verify(password, shoppingUser.getPassword());
		if (!verify) {
			throw new BusException(CodeEnum.USERNAME_PASSWORD_ERROR);
		}
		
		// 3.生成JWT令牌，返回令牌
		String sign = JwtUtils.sign(shoppingUser.getId(),shoppingUser.getUsername());
		
		return sign;
		
	}
	
	/**
	 * 注册
	 *
	 * @param shoppingUser
	 */
	public void register(ShoppingUser shoppingUser) {
		//1.验证手机号是否存在
		String phone = shoppingUser.getPhone();
		QueryWrapper<ShoppingUser> wrapper = new QueryWrapper();
		wrapper.eq("phone", phone);
		List<ShoppingUser> shoppingUsers = shoppingUserMapper.selectList(wrapper);
		if (shoppingUsers != null && shoppingUsers.size() > 0) {
			throw new BusException(CodeEnum.REGISTER_REPEAT_PHONE_ERROR);
		}
		// 2.验证用户名是否存在
		
		String username = shoppingUser.getUsername();
		QueryWrapper<ShoppingUser> queryWrapper1 = new QueryWrapper();
		queryWrapper1.eq("username", username);
		List<ShoppingUser> shoppingUsers1 = shoppingUserMapper.selectList(queryWrapper1);
		if (shoppingUsers1 != null && shoppingUsers1.size() > 0) {
			throw new BusException(CodeEnum.REGISTER_REPEAT_NAME_ERROR);
		}
		
		//3.保存用户信息新增用户
		
		shoppingUser.setStatus("Y");
		shoppingUser.setPassword(Md5Util.encode(shoppingUser.getPassword()));
		shoppingUserMapper.insert(shoppingUser);
	}
	
	/**
	 * 登录时向redis保存手机号+验证码
	 *
	 * @param phone
	 * @param checkCode
	 */
	public void saveLoginCheckCode(String phone, String checkCode) {
		
		ValueOperations valueOperations = redisTemplate.opsForValue();
		valueOperations.set("loginCode:" + phone, checkCode, 300, TimeUnit.SECONDS);
		
	}
	
	/**
	 * 手机号验证码登录
	 *
	 * @param phone
	 * @param checkCode
	 * @return
	 */
	// 验证登录验证码
	@Override
	public String loginCheckCode(String phone, String checkCode) {
		// 验证用户传入的手机号验证码是否在redis中存在
		ValueOperations valueOperations = redisTemplate.opsForValue();
		Object checkCodeRedis = valueOperations.get("loginCode:" + phone);
		if (!checkCode.equals(checkCodeRedis)) {
			throw new BusException(CodeEnum.LOGIN_CODE_ERROR);
		}
		// 登录成功，查询用户
		QueryWrapper<ShoppingUser> queryWrapper = new QueryWrapper();
		queryWrapper.eq("phone", phone);
		ShoppingUser shoppingUser = shoppingUserMapper.selectOne(queryWrapper);
	
		// 3.生成JWT令牌，返回令牌
		String sign = JwtUtils.sign(shoppingUser.getId(),shoppingUser.getUsername());
		
		return sign;
		
	}
	
	
	/**
	 * 获取用户名
	 *
	 * @param token
	 * @return
	 */
	public String getName(String token) {
		//jwt的解密方法，从令牌中获取username用户名
		Map<String, Object> map = JwtUtils.verify(token);
		String username = (String) map.get("username");
		return username;
	}
	
	/**
	 * 根据id获取登录用户
	 *
	 * @param token
	 * @return
	 */
	public ShoppingUser getLoginUser(String token) {
		// 从令牌中获取用户id
		Map<String, Object> map = JwtUtils.verify(token);
		Long userId = (Long) map.get("userId");
		// 根据id查询用户
		QueryWrapper<ShoppingUser> queryWrapper = new QueryWrapper();
		queryWrapper.eq("id", userId);
		ShoppingUser shoppingUser = shoppingUserMapper.selectOne(queryWrapper);
		return shoppingUser;
	}
	
	/**
	 * 判断手机号是否注册且状态正常
	 * @param phone
	 */
	public void checkPhone(String phone) {
		QueryWrapper<ShoppingUser> wrapper = new QueryWrapper();
		wrapper.eq("phone", phone);
		ShoppingUser shoppingUser = shoppingUserMapper.selectOne(wrapper);
		//判断该手机号是否注册
		if (shoppingUser == null){
			throw new BusException(CodeEnum.PHONE_NOT_REGISTER);
		}
		//判断该手机号状态是否正常
		if (!"Y".equals(shoppingUser.getStatus())){
			throw new BusException(CodeEnum.PHONE_STATUS_ERROR);
		}
		
	}
}
